#coding=utf-8
#LightCam Syslog日志解析程序
#init by hfh 20150212

#import multiprocessing,subprocess
import socket,os,time,re,traceback,subprocess,sys,pymongo
import lc_libs

def ClearEvents():
	expr={'Severity':{"$gt":0},'Type':2}
	sortcont=[("_id",pymongo.ASCENDING)]
	opts=db.queryData(status_table,expr,sortcont,0)
	res=db.genResult(opts)
	print res
	for line in res:
		expr={'Node':line['Node'],'AlertGroup':line['AlertGroup'],'AlertKey':line['AlertKey'],'Severity':{"$gt":0}}
		datas={'Severity':0}
		db.updateData(status_table,expr,datas)
	
	#exit(0)

def initTableFields():
	TableFields={
		'Identifier':'',
		'Serial':0,
		'Node':'',
		'NodeAlias':'',
		'Manager':'',
		'Agent':'',
		'AlertGroup':'',
		'AlertKey':'',
		'Severity':0,
		'Summary':'',
		'LastModified':0,
		'FirstOccurrence':0,
		'LastOccurrence':0,
		'Type':0,
		'Tally':0,
		'OwnerUID':'',
		'OwnerGID':'',
		'Acknowledged':0,
		'ServerName':'',
		'ServerSerial':0,
		'OSeverity':0,
		'SoundStatus':0
		}
	return TableFields

def func(ServerName,SyslogFile):
	
	#读取syslog日志文件
	#file=open(SyslogFile,'r')
	#file.readlines()
	file=open(SyslogFile,'rb')
	pointer=os.path.getsize(SyslogFile)
	file.seek(pointer,0)
	
	while True:
		time.sleep(1)
		#ClearEvents()
		try:
			nsize=os.path.getsize(SyslogFile)
			if nsize < pointer:
				pointer=0
				file.seek(pointer,0)
			
			#执行日志监控
			for filecontent in file.readlines():
				filecontent=filecontent.strip('\r\n')
				print filecontent
				
				if str(filecontent) == "":
					time.sleep(1)
					continue
					
				try:
					filecontent=filecontent.decode('gbk').encode('utf8')
				except:
					pass
				
				filecontents=filecontent.split()
				if len(filecontents)<4:
					continue
				
				TableFields=initTableFields()
				TableFields['Manager']=agent_hostname
				
				if "LightCam" in filecontent:
					TableFields['Agent']='LightCam'
					res=re.findall(r"Node:(.*) AlertGroup",filecontent,re.S)
					if len(res) <> 0:
						TableFields['Node']=res[0]
					res=re.findall(r"AlertGroup:(.*) AlertKey",filecontent,re.S)
					if len(res) <> 0:
						TableFields['AlertGroup']=res[0]
					res=re.findall(r"AlertKey:(.*) Severity",filecontent,re.S)
					if len(res) <> 0:
						TableFields['AlertKey']=res[0]
					res=re.findall(r"Severity:(.*) Type",filecontent,re.S)
					if len(res) <> 0:
						TableFields['Severity']=int(res[0])
					res=re.findall(r"Type:(.*) Summary",filecontent,re.S)
					if len(res) <> 0:
						TableFields['Type']=int(res[0])
					res=re.findall(r"Summary:(.*)$",filecontent,re.S)
					if len(res) <> 0:
						TableFields['Summary']=res[0].strip('\n')
				elif re.search("%%[0-9]{2}[A-Za-z]+/[0-9]/[A-Za-z_]+\([A-Za-z]\)",filecontent):
					#Nov 16 10:28:58 Nov 16 2015 02:29:00.063 D_JY_GL_S02 %%01IFNET/2/linkDown_active(l):CID=0x807a040a-alarmID=0x08520003;The interface status changes. (ifName=10GE1/0/15, AdminStatus=UP, OperStatus=DOWN, Reason=Interface physical link is down, mainName=10GE1/0/15)#015
					#默认处理规则
					TableFields['Agent']='HuaWei'
					TableFields['Severity']=2
					TableFields['Type']=1
					res=re.findall(r"%%[0-9]{2}([A-Za-z]+)/[0-9]/[A-Za-z_]+\([A-Za-z]\)",filecontent,re.S)
					AlertType=res[0]
					res=re.findall(r"%%[0-9]{2}[A-Za-z]+/([0-9])/[A-Za-z_]+\([A-Za-z]\)",filecontent,re.S)
					AlertSeverity=res[0]
					res=re.findall(r"%%[0-9]{2}[A-Za-z]+/[0-9]/([A-Za-z_]+)\([A-Za-z]\)",filecontent,re.S)
					AlertName=res[0]
					TableFields['AlertGroup']="%s-%s" % (AlertType,AlertName)
					res=re.findall(r"([A-Za-z0-9_-]+) %%[0-9]{2}[A-Za-z]+/[0-9]/[A-Za-z_]+\([A-Za-z]\)",filecontent,re.S)
					if len(res)<>0:
						TableFields['Node']=res[0]
					TableFields['Summary']=filecontent
					
					#特殊化处理
					if AlertType=='IFPDT':
						if AlertName=='IF_STATE':
							#Dec 18 17:23:04 172.20.254.242  2015 09:23:04.837.1 D_Dutyroom_S02 %%01IFPDT/4/IF_STATE(l)[2562]:Interface GigabitEthernet0/0/1 has turned into DOWN state.
							#Dec 18 17:23:32 172.20.254.242  2015 09:23:32.937.1 D_Dutyroom_S02 %%01IFPDT/4/IF_STATE(l)[2563]:Interface GigabitEthernet0/0/1 has turned into UP state.
							Temp_State=""
							res=re.findall(r"Interface (.*) has turned into .* state",filecontent,re.S)
							if len(res)<>0:
								TableFields['AlertKey']=res[0]
							res=re.findall(r"Interface .* has turned into (.*) state",filecontent,re.S)
							if len(res)<>0:
								Temp_State=res[0]
								if Temp_State.upper()=='DOWN':
									TableFields['Severity']=4
									TableFields['Type']=1
								elif Temp_State.upper()=='UP':
									TableFields['Severity']=1
									TableFields['Type']=2
					elif AlertType=='IFNET':
						if AlertName=='LINK_STATE':
							Temp_State=""
							#Dec 21 14:06:52 172.20.254.31  2015 06:06:52.800.4 D_JR_JR_R01 %%01IFNET/4/LINK_STATE(l)[5193]:The line protocol IP on the interface GigabitEthernet6/1/5 has entered the DOWN state.
							#Dec 21 14:07:01 172.20.254.31  2015 06:07:00.960.5 D_JR_JR_R01 %%01IFNET/4/LINK_STATE(l)[5196]:The line protocol IP on the interface GigabitEthernet6/1/5 has entered the UP state.
							res=re.findall(r"The line protocol IP on the interface (.*) has entered the .* state",filecontent,re.S)
							if len(res)<>0:
								TableFields['AlertKey']=res[0]
							res=re.findall(r"The line protocol IP on the interface .* has entered the (.*) state",filecontent,re.S)
							if len(res)<>0:
								Temp_State=res[0]
							#Dec 15 10:54:02 172.20.254.21 54:02 D_JR_GL_F01 %%01IFNET/2/LINK_STATE(l): Line protocol on interface GigabitEthernet3/0/9 has turned into DOWN state.
							#Dec 15 10:57:40 172.20.254.21 57:40 D_JR_GL_F01 %%01IFNET/2/LINK_STATE(l): Line protocol on interface GigabitEthernet3/0/9 has turned into UP state.
							res=re.findall(r"Line protocol on interface (.*) has turned into .* state",filecontent,re.S)
							if len(res)<>0:
								TableFields['AlertKey']=res[0]
							res=re.findall(r"Line protocol on interface .* has turned into (.*) state",filecontent,re.S)
							if len(res)<>0:
								Temp_State=res[0]
							if Temp_State.upper()=='DOWN':
								TableFields['Severity']=4
								TableFields['Type']=1
							elif Temp_State.upper()=='UP':
								TableFields['Severity']=1
								TableFields['Type']=2
						elif AlertName in ('linkDown_active','linkDown_clear'):
							AlertName='LINKSTATUS'
							TableFields['AlertGroup']="%s-%s" % (AlertType,AlertName)
							Temp_State=""
							#Dec 15 10:23:16 172.20.254.23  2015 02:23:16.303 D_JR_HJ_S01 %%01IFNET/2/linkDown_active(l):CID=0x807a040a-alarmID=0x08520003;The interface status changes. (ifName=10GE1/0/42, AdminStatus=DOWN, OperStatus=DOWN, Reason=The interface is shut down, mainName=10GE1/0/42)#015
							#Dec 15 10:24:42 172.20.254.23  2015 02:24:36.778 D_JR_HJ_S01 %%01IFNET/2/linkDown_clear(l):CID=0x807a040a-alarmID=0x08520003-clearType=service_resume;The interface status changes. (ifName=10GE1/0/42, AdminStatus=UP, OperStatus=UP, Reason=Interface physical link is up, mainName=10GE1/0/42)#015
							res=re.findall(r"ifName=([0-9A-Za-z/]+),",filecontent,re.S)
							if len(res)<>0:
								TableFields['AlertKey']=res[0]
							res=re.findall(r"OperStatus=([A-Za-z]+),",filecontent,re.S)
							if len(res)<>0:
								Temp_State=res[0]
							if Temp_State.upper()=='DOWN':
								TableFields['Severity']=4
								TableFields['Type']=1
							elif Temp_State.upper()=='UP':
								TableFields['Severity']=1
								TableFields['Type']=2
				else:
					TableFields['Agent']="Unknow"
					TableFields['AlertGroup']="未知事件"
					continue
					
				#print TableFields
				TableFields['OSeverity']=TableFields['Severity']
				TableFields['Identifier']="%s %s %s %s %s %s %s" % (TableFields['Node'],TableFields['AlertGroup'],TableFields['AlertKey'],TableFields['Severity'],TableFields['Type'],TableFields['Manager'],TableFields['Agent'])
				
				#更新实时事件库
				db.update_alert_status(status_table,TableFields,logfile)
				
				#更新历史事件库
				db.update_alert_history(history_table,TableFields,logfile)
		
		except Exception:
			excinfo=traceback.format_exc()
			print excinfo
			logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
			logfile.write(logdate+" :\n"+excinfo+"\n")
			logfile.flush()
			time.sleep(1)
		#等待
		time.sleep(0.1)

if __name__ == "__main__":


	lchome=lc_libs.lc_getlchome()
	scname=sys.argv[0].split('.')[0]
	logfilename=lchome+'/log/'+scname+'.log'
	confname=lchome+'/conf/'+scname+'.conf'
	
	today=time.strftime('%Y%m%d',time.localtime())
	comd="mv %s %s.%s" % (logfilename,logfilename,today)
	os.system(comd)
	
	logfile=file(logfilename,'a')
	logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
	logfile.write(logdate+" Started.\n")
	logfile.flush()
	
	agent_hostname=lc_libs.lc_gethostname()
	ServerName="LCS"
	SyslogFile="/var/log/lclog"
	
	for line in open(confname):
		if line[0] == '#':
			continue
		if "ServerName" in line:
			ServerName=line.strip('\n').split(":")[1]
		if "SyslogFile" in line:
			SyslogFile=line.strip('\n').split(":")[1]
	
	#初始化alert数据库
	#dbfile="../db/lc_alert.db"
	#flags表
	#tablename="lc_flags"
	#tablefield="Name varchar(32),Value varchar(32)"
	#dbf=lc_libs.lc_dboperater(dbfile,tablename,tablefield)
	#dbf.create_db()
	#status表
	#tablename="lc_status"
	#tablefield="Node varchar(32),AlertGroup varchar(64),AlertKey varchar(64),Severity varchar(8),Type varchar(8),LastOccurrence varchar(32),Summary varchar(256)"
	#tablefield='''
		#Identifier varchar(256),
		#Serial varchar(32),
		#Node varchar(32),
		#NodeAlias varchar(32),
		#Manager varchar(32),
		#Agent varchar(32),
		#AlertGroup varchar(64),
		#AlertKey varchar(64),
		#Summary varchar(1024),
		#Type varchar(8),
		#Tally varchar(8),
		#Severity varchar(8),
		#OSeverity varchar(8),
		#OwnerUID varchar(8),
		#OwnerGID varchar(8),
		#Acknowledged varchar(8),
		#LastModified varchar(8),
		#FirstOccurrence varchar(32),
		#LastOccurrence varchar(32),
		#ServerName varchar(32),
		#ServerSerial varchar(32),
		#EventId varchar(32),
		#SoundStatus varchar(32)
	#'''
	#dbs=lc_libs.lc_dboperater(dbfile,tablename,tablefield)
	#dbs.create_db()
	#history表
	#tablename="lc_history"
	#tablefield="Node varchar(32),AlertGroup varchar(64),AlertKey varchar(64),Severity varchar(8),Type varchar(8),LastOccurrence varchar(32),Summary varchar(256)"
	#tablefield='''
		#Identifier varchar(256),
		#Serial varchar(32),
		#Node varchar(32),
		#NodeAlias varchar(32),
		#Manager varchar(32),
		#Agent varchar(32),
		#AlertGroup varchar(64),
		#AlertKey varchar(64),
		#Summary varchar(1024),
		#Type varchar(8),
		#Tally varchar(8),
		#Severity varchar(8),
		#OSeverity varchar(8),
		#OwnerUID varchar(8),
		#OwnerGID varchar(8),
		#Acknowledged varchar(8),
		#LastModified varchar(8),
		#FirstOccurrence varchar(32),
		#LastOccurrence varchar(32),
		#ServerName varchar(32),
		#ServerSerial varchar(32),
		#EventId varchar(32),
		#SoundStatus varchar(32)
	#'''
	#dbh=lc_libs.lc_dboperater(dbfile,tablename,tablefield)
	#dbh.create_db()



	try:
		#初始化数据库
		
		db=lc_libs.lc_mongodb_operater('127.0.0.1',27017)

		db.connect()
		Conn=db.getConn()
		if Conn==None:
			print "Can not Connect to the MondbDB"
			exit(0)
		
		alert_dbname='lc_alert'
		status_tablename='lc_status'
		history_tablename="lc_history"
		
		alert_db=db.useDatabase(alert_dbname)
		status_table=db.UseCollection(alert_db,status_tablename)
		history_table=db.UseCollection(alert_db,history_tablename)

	except Exception:
		excinfo=traceback.format_exc()
		logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
		logfile.write(logdate+" 初始化数据库失败:\n"+excinfo+"\n")
		logfile.flush()
		exit(0)


	#TableFields={}
	func(ServerName,SyslogFile)
	
